using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Diagnostics;


namespace jaysJourney_v01.Utils
{
    public class SpriteAnimator
    {
        /**
         * MEMBER VARIABLES
         * */

        // Common

        private SpriteBatch parentSpriteBatch;
        private Texture2D animationSprite;

        private int frameWidth;
        private int frameHeight;
        private int totalWidth;
        private int totalHeight;

        private bool centerHor;

        // Animation

        private float fps;
        private bool isRunning = false;
        private bool isLooping;
        public int curFrame = 0;
        private int totalFrames;
        private double curTime = 0;
        private double pauseTime = 0;

        private bool isFinished = false;

        /**
         * METHODS
         * */

        // Constructor

        public SpriteAnimator(SpriteBatch parentSpriteBatch, Texture2D sprite, float fps, int totalFrames, int frameWidth, int frameHeight, int totalWidth, int totalHeight, bool isLooping, bool centerHor)
        {
            this.parentSpriteBatch = parentSpriteBatch;
            this.animationSprite = sprite;
            this.fps = fps;
            this.totalFrames = totalFrames;
            this.frameWidth = frameWidth;
            this.frameHeight = frameHeight;
            this.totalWidth = totalWidth;
            this.totalHeight = totalHeight;
            this.isLooping = isLooping;
            this.centerHor = centerHor;
        }

        // Play Animation

        public void animate(GameTime gameTime, Vector2 position, bool lookRight)
        {
            if (!isRunning && pauseTime > 0)
            {
                pauseTime -= (double)gameTime.ElapsedGameTime.Milliseconds / 1000d;
                if (pauseTime <= 0) this.isRunning = true;
            }
            if (isRunning)
            {
                this.curTime += (double)gameTime.ElapsedGameTime.Milliseconds / 1000d; // add gameTime

                if(this.curTime >= (1.0d / (double)fps)) // frame math
                {
                    this.curTime = 0; // reset curTime
                    this.curFrame++; // add frame

                    // loop or let last frame
                    if (this.curFrame >= this.totalFrames && isLooping) this.curFrame = 0;
                    else if (this.curFrame >= this.totalFrames && !isLooping)
                    {
                        this.curFrame = this.totalFrames - 1;
                        this.isFinished = true;
                    }
                }

                // math current pos
                int posX = this.frameWidth * this.curFrame;
                int posY = 0;

                // do break if posX >= totalWidth
                while ((posX - this.totalWidth) >= 0)
                {
                    posX -= this.totalWidth;
                    posY += this.frameHeight;
                }

                // Calc Final Position
                int finalPosX = (int)position.X;
                //if (this.centerHor) finalPosX -= (this.frameWidth / 2);

                // Draw
                if (lookRight) this.parentSpriteBatch.Draw(this.animationSprite, new Rectangle(finalPosX, (int)position.Y, this.frameWidth, this.frameHeight), new Rectangle(posX, posY, this.frameWidth, this.frameHeight), Color.White, 0, new Vector2(0, 0), SpriteEffects.None, 1);
                else this.parentSpriteBatch.Draw(this.animationSprite, new Rectangle(finalPosX, (int)position.Y, this.frameWidth, this.frameHeight), new Rectangle(posX, posY, this.frameWidth, this.frameHeight), Color.White, 0, new Vector2(0, 0), SpriteEffects.FlipHorizontally, 1);
            } 
        }

        // Start Animation

        public void play()
        {
            this.isRunning = true;
        }

        // Stop Animation

        public void stop()
        {
            this.isRunning = false;
            this.curFrame = 0;
            this.isFinished = false;
        }

        // Pause Animation

        public void pause()
        {
            this.isRunning = false;
        }
        public void pause(double time)
        {
            this.isRunning = false;
            this.pauseTime = time;
        }

        // Reset Animation

        public void reset()
        {
            this.curFrame = 0;
            this.isFinished = false;
        }

        // check if finished

        public bool hasFinished()
        {
            return this.isFinished;
        }
    }
}
